package my.learn.server.lazy.standalone.application.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
//import org.framework.lazy.cloud.network.heartbeat.common.NettyClientVisitorContext;
//import org.framework.lazy.cloud.network.heartbeat.common.adapter.ChannelFlowAdapter;
////import org.framework.lazy.cloud.network.heartbeat.server.netty.tcp.socket.NettyTcpServerPermeateClientVisitorSocket;
////import org.framework.lazy.cloud.network.heartbeat.server.properties.ServerNodeProperties;
////import org.framework.lazy.cloud.network.heartbeat.server.standalone.application.LazyServerPermeateClientMappingApplication;
////import org.framework.lazy.cloud.network.heartbeat.server.standalone.application.assembler.LazyNettyServerPermeateClientMappingDTOAssembler;
////import org.framework.lazy.cloud.network.heartbeat.server.standalone.application.command.lazy.netty.server.permeate.client.mapping.*;
////import org.framework.lazy.cloud.network.heartbeat.server.standalone.application.dto.LazyServerPermeateClientMappingDTO;
////import org.framework.lazy.cloud.network.heartbeat.server.standalone.domain.model.lazy.netty.server.permeate.client.mapping.LazyNettyServerPermeateClientMapping;
////import org.framework.lazy.cloud.network.heartbeat.server.standalone.domain.model.lazy.netty.server.permeate.client.mapping.LazyNettyServerPermeateClientMappingRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import my.learn.common.adapter.ChannelFlowAdapter;
import my.learn.common.web.response.Result;
import my.learn.server.lazy.netty.tcp.socket.NettyTcpServerPermeateClientVisitorSocket;
import my.learn.server.lazy.standalone.application.LazyServerPermeateClientMappingApplication;
import my.learn.server.lazy.standalone.application.command.lazy.netty.server.permeate.client.mapping.*;
import my.learn.server.lazy.standalone.application.dto.LazyServerPermeateClientMappingDTO;
import my.learn.server.lazy.standalone.domain.model.lazy.netty.server.permeate.client.mapping.LazyNettyServerPermeateClientMapping;
import my.learn.server.lazy.standalone.infrastructure.entity.LazyNettyServerPermeateClientMappingDO;
import my.learn.server.service.ILazyNettyServerPermeateClientMappingDOService;
//import org.wu.framework.core.utils.ObjectUtils;
//import org.wu.framework.database.lazy.web.plus.stereotype.LazyApplication;
//import org.wu.framework.lazy.orm.core.persistence.reverse.lazy.ddd.DefaultDDDLazyApplicationImpl;
//import org.wu.framework.lazy.orm.database.lambda.domain.LazyPage;
//import org.wu.framework.web.response.Result;
//import org.wu.framework.web.response.ResultFactory;

import java.util.List;
import java.util.stream.Collectors;

/**
 * describe 内网穿透映射
 *
 * @author
 * @date 2023/12/29 05:21 下午
 * @see DefaultDDDLazyApplicationImpl
 **/
@Slf4j
//@LazyApplication
@Component
public class LazyServerPermeateClientMappingApplicationImpl implements LazyServerPermeateClientMappingApplication {
    @Autowired
    ILazyNettyServerPermeateClientMappingDOService lazyNettyServerPermeateClientMappingDOService;
    @Override
    public Result<LazyNettyServerPermeateClientMapping> story(LazyServerPermeateClientMappingStoryCommand lazyServerPermeateClientMappingStoryCommand) {
        return null;
    }

    @Override
    public Result<List<LazyNettyServerPermeateClientMapping>> batchStory(List<LazyServerPermeateClientMappingStoryCommand> lazyServerPermeateClientMappingStoryCommandList) {
        return null;
    }

    @Override
    public Result<LazyNettyServerPermeateClientMapping> updateOne(LazyServerPermeateClientMappingUpdateCommand lazyServerPermeateClientMappingUpdateCommand) {
        return null;
    }

    @Override
    public Result<LazyServerPermeateClientMappingDTO> findOne(LazyServerPermeateClientMappingQueryOneCommand lazyServerPermeateClientMappingQueryOneCommand) {
        return null;
    }

    @Override
    public Result<List<LazyServerPermeateClientMappingDTO>> findList(LazyServerPermeateClientMappingQueryListCommand lazyServerPermeateClientMappingQueryListCommand) {
        return null;
    }

    @Override
    public Result<LazyNettyServerPermeateClientMapping> remove(LazyServerPermeateClientMappingRemoveCommand lazyServerPermeateClientMappingRemoveCommand) {
        return null;
    }



//    @Resource
//    LazyNettyServerPermeateClientMappingRepository lazyNettyServerPermeateClientMappingRepository;
//
    @Resource
ChannelFlowAdapter channelFlowAdapter;
//
//    @Resource
//    ServerNodeProperties serverNodeProperties;
//
//
//    /**
//     * describe 新增内网穿透映射
//     *
//     * @param lazyServerPermeateClientMappingStoryCommand 新增内网穿透映射
//     * @return {@link Result<    LazyNettyServerPermeateClientMapping    >} 内网穿透映射新增后领域对象
//     * @author
//     * @date 2023/12/29 05:21 下午
//     **/
//
//    @Override
//    public Result<LazyNettyServerPermeateClientMapping> story(LazyServerPermeateClientMappingStoryCommand lazyServerPermeateClientMappingStoryCommand) {
//        LazyNettyServerPermeateClientMapping lazyNettyServerPermeateClientMapping = LazyNettyServerPermeateClientMappingDTOAssembler.INSTANCE.toInternalNetworkPenetrationMapping(lazyServerPermeateClientMappingStoryCommand);
//        lazyNettyServerPermeateClientMapping.setIsDeleted(false);
//        String serverId = serverNodeProperties.getNodeId();
//        lazyNettyServerPermeateClientMapping.setServerId(serverId);
//
//        String clientId = lazyNettyServerPermeateClientMapping.getClientId();
//        String clientTargetIp = lazyNettyServerPermeateClientMapping.getClientTargetIp();
//        Integer clientTargetPort = lazyNettyServerPermeateClientMapping.getClientTargetPort();
//        Integer visitorPort = lazyNettyServerPermeateClientMapping.getVisitorPort();
//
//        // 创建访客通道池
//
//        this.changeSocket(clientId, clientTargetIp, clientTargetPort, visitorPort);
//        return lazyNettyServerPermeateClientMappingRepository.story(lazyNettyServerPermeateClientMapping);
//    }
//
//    /**
//     * describe 批量新增内网穿透映射
//     *
//     * @param lazyServerPermeateClientMappingStoryCommandList 批量新增内网穿透映射
//     * @return {@link Result<List<   LazyNettyServerPermeateClientMapping   >>} 内网穿透映射新增后领域对象集合
//     * @author
//     * @date 2023/12/29 05:21 下午
//     **/
//
//    @Transactional
//    @Override
//    public Result<List<LazyNettyServerPermeateClientMapping>> batchStory(List<LazyServerPermeateClientMappingStoryCommand> lazyServerPermeateClientMappingStoryCommandList) {
//        List<LazyNettyServerPermeateClientMapping> lazyNettyServerPermeateClientMappingList =
//                lazyServerPermeateClientMappingStoryCommandList
//                        .stream()
//                        .map(lazyInternalNetworkPenetrationMappingStoryCommand -> {
//                            LazyNettyServerPermeateClientMapping lazyNettyServerPermeateClientMapping = LazyNettyServerPermeateClientMappingDTOAssembler.INSTANCE.toInternalNetworkPenetrationMapping(lazyInternalNetworkPenetrationMappingStoryCommand);
//                            String serverId = serverNodeProperties.getNodeId();
//                            lazyNettyServerPermeateClientMapping.setServerId(serverId);
//                            return lazyNettyServerPermeateClientMapping;
//                        })
//                        .collect(Collectors.toList());
//
//        Result<List<LazyNettyServerPermeateClientMapping>> batchStory = lazyNettyServerPermeateClientMappingRepository.batchStory(lazyNettyServerPermeateClientMappingList);
//        // 开启端口
//        for (LazyNettyServerPermeateClientMapping lazyNettyServerPermeateClientMapping : lazyNettyServerPermeateClientMappingList) {
//            String clientId = lazyNettyServerPermeateClientMapping.getClientId();
//            String clientTargetIp = lazyNettyServerPermeateClientMapping.getClientTargetIp();
//            Integer clientTargetPort = lazyNettyServerPermeateClientMapping.getClientTargetPort();
//            Integer visitorPort = lazyNettyServerPermeateClientMapping.getVisitorPort();
//            this.changeSocket(clientId, clientTargetIp, clientTargetPort, visitorPort);
//        }
//        return batchStory;
//    }
//
//    /**
//     * describe 更新内网穿透映射
//     *
//     * @param lazyServerPermeateClientMappingUpdateCommand 更新内网穿透映射
//     * @return {@link Result<   LazyNettyServerPermeateClientMapping   >} 内网穿透映射领域对象
//     * @author
//     * @date 2023/12/29 05:21 下午
//     **/
//
//    @Transactional
//    @Override
//    public Result<LazyNettyServerPermeateClientMapping> updateOne(LazyServerPermeateClientMappingUpdateCommand lazyServerPermeateClientMappingUpdateCommand) {
//        LazyNettyServerPermeateClientMapping lazyNettyServerPermeateClientMapping = LazyNettyServerPermeateClientMappingDTOAssembler.INSTANCE.toInternalNetworkPenetrationMapping(lazyServerPermeateClientMappingUpdateCommand);
//        String serverId = serverNodeProperties.getNodeId();
//        lazyNettyServerPermeateClientMapping.setServerId(serverId);
//        // 删除绑定数据
//        Result<LazyNettyServerPermeateClientMapping> story = lazyNettyServerPermeateClientMappingRepository.story(lazyNettyServerPermeateClientMapping);
//        String clientId = lazyNettyServerPermeateClientMapping.getClientId();
//        String clientTargetIp = lazyNettyServerPermeateClientMapping.getClientTargetIp();
//        Integer clientTargetPort = lazyNettyServerPermeateClientMapping.getClientTargetPort();
//        Integer visitorPort = lazyNettyServerPermeateClientMapping.getVisitorPort();
//        this.changeSocket(clientId, clientTargetIp, clientTargetPort, visitorPort);
//        return story;
//    }
//
//
//    /**
//     * 变更 网络穿透
//     *
//     * @param clientId         客户端ID
//     * @param clientTargetIp   客户端目标IP
//     * @param clientTargetPort 客户端莫表端口
//     * @param visitorPort      访客端口
//     */
//    private void changeSocket(String clientId, String clientTargetIp, Integer clientTargetPort, Integer visitorPort) {
//        // 删除 客户端映射
//        this.changeCloseSocket(clientId, visitorPort);
//        // 更新 客户端映射
//        createVisitor(clientId, clientTargetIp, clientTargetPort, visitorPort);
//    }
//
//
//    /**
//     * 删除 通道
//     *
//     * @param clientId    客户端ID
//     * @param visitorPort 访客端口
//     */
//    private void changeCloseSocket(String clientId, Integer visitorPort) {
//        // 删除 客户端映射
//        List<NettyTcpServerPermeateClientVisitorSocket> nettyTcpServerPermeateClientVisitorSocketList = NettyClientVisitorContext.getVisitorSockets(clientId);
//        if (!ObjectUtils.isEmpty(nettyTcpServerPermeateClientVisitorSocketList)) {
//            nettyTcpServerPermeateClientVisitorSocketList = nettyTcpServerPermeateClientVisitorSocketList.stream()
//                    .filter(nettyTcpServerPermeateClientVisitorSocket -> nettyTcpServerPermeateClientVisitorSocket.getVisitorPort() == visitorPort).toList();
//            if (!ObjectUtils.isEmpty(nettyTcpServerPermeateClientVisitorSocketList)) {
//                // 关闭端口
//                for (NettyTcpServerPermeateClientVisitorSocket nettyTcpServerPermeateClientVisitorSocket : nettyTcpServerPermeateClientVisitorSocketList) {
//                        nettyTcpServerPermeateClientVisitorSocket.close();
//                }
//                // 关闭通道 socket
//
//            }
//        }
//    }
//
//    /**
//     * describe 查询单个内网穿透映射
//     *
//     * @param lazyServerPermeateClientMappingQueryOneCommand 查询单个内网穿透映射
//     * @return {@link Result<   LazyServerPermeateClientMappingDTO   >} 内网穿透映射DTO对象
//     * @author
//     * @date 2023/12/29 05:21 下午
//     **/
//    @Override
//    public Result<LazyServerPermeateClientMappingDTO> findOne(LazyServerPermeateClientMappingQueryOneCommand lazyServerPermeateClientMappingQueryOneCommand) {
//        LazyNettyServerPermeateClientMapping lazyNettyServerPermeateClientMapping = LazyNettyServerPermeateClientMappingDTOAssembler.INSTANCE.toInternalNetworkPenetrationMapping(lazyServerPermeateClientMappingQueryOneCommand);
//        String serverId = serverNodeProperties.getNodeId();
//        lazyNettyServerPermeateClientMapping.setServerId(serverId);
//        return lazyNettyServerPermeateClientMappingRepository.findOne(lazyNettyServerPermeateClientMapping).convert(LazyNettyServerPermeateClientMappingDTOAssembler.INSTANCE::fromInternalNetworkPenetrationMapping);
//    }
//
//    /**
//     * describe 查询多个内网穿透映射
//     *
//     * @param lazyServerPermeateClientMappingQueryListCommand 查询多个内网穿透映射
//     * @return {@link Result<List<  LazyServerPermeateClientMappingDTO  >>} 内网穿透映射DTO对象
//     * @author
//     * @date 2023/12/29 05:21 下午
//     **/
//
//    @Override
//    public Result<List<LazyServerPermeateClientMappingDTO>> findList(LazyServerPermeateClientMappingQueryListCommand lazyServerPermeateClientMappingQueryListCommand) {
//        LazyNettyServerPermeateClientMapping lazyNettyServerPermeateClientMapping = LazyNettyServerPermeateClientMappingDTOAssembler.INSTANCE.toInternalNetworkPenetrationMapping(lazyServerPermeateClientMappingQueryListCommand);
//
//        String serverId = serverNodeProperties.getNodeId();
//        lazyNettyServerPermeateClientMapping.setServerId(serverId);
//        return lazyNettyServerPermeateClientMappingRepository.findList(lazyNettyServerPermeateClientMapping).convert(internalNetworkPenetrationMappings -> internalNetworkPenetrationMappings.stream().map(LazyNettyServerPermeateClientMappingDTOAssembler.INSTANCE::fromInternalNetworkPenetrationMapping).collect(Collectors.toList()));
//    }
//
//    /**
//     * describe 分页查询多个内网穿透映射
//     *
//     * @param lazyServerPermeateClientMappingQueryListCommand 分页查询多个内网穿透映射
//     * @return {@link Result<LazyPage<  LazyServerPermeateClientMappingDTO  >>} 分页内网穿透映射DTO对象
//     * @author
//     * @date 2023/12/29 05:21 下午
//     **/
//
//    @Override
//    public Result<LazyPage<LazyServerPermeateClientMappingDTO>> findPage(int size, int current, LazyServerPermeateClientMappingQueryListCommand lazyServerPermeateClientMappingQueryListCommand) {
//        LazyNettyServerPermeateClientMapping lazyNettyServerPermeateClientMapping = LazyNettyServerPermeateClientMappingDTOAssembler.INSTANCE.toInternalNetworkPenetrationMapping(lazyServerPermeateClientMappingQueryListCommand);
//        String serverId = serverNodeProperties.getNodeId();
//        lazyNettyServerPermeateClientMapping.setServerId(serverId);
//        return lazyNettyServerPermeateClientMappingRepository.findPage(size, current, lazyNettyServerPermeateClientMapping).convert(page -> page.convert(LazyNettyServerPermeateClientMappingDTOAssembler.INSTANCE::fromInternalNetworkPenetrationMapping));
//    }
//
//    /**
//     * describe 删除内网穿透映射
//     *
//     * @param lazyServerPermeateClientMappingRemoveCommand 删除内网穿透映射
//     * @return {@link Result<   LazyNettyServerPermeateClientMapping   >} 内网穿透映射
//     * @author
//     * @date 2023/12/29 05:21 下午
//     **/
//
//    @Transactional
//    @Override
//    public Result<LazyNettyServerPermeateClientMapping> remove(LazyServerPermeateClientMappingRemoveCommand lazyServerPermeateClientMappingRemoveCommand) {
//        LazyNettyServerPermeateClientMapping lazyNettyServerPermeateClientMapping = LazyNettyServerPermeateClientMappingDTOAssembler.INSTANCE.toInternalNetworkPenetrationMapping(lazyServerPermeateClientMappingRemoveCommand);
//        String serverId = serverNodeProperties.getNodeId();
//        lazyNettyServerPermeateClientMapping.setServerId(serverId);
//        Result<LazyNettyServerPermeateClientMapping> remove = lazyNettyServerPermeateClientMappingRepository.remove(lazyNettyServerPermeateClientMapping);
//        // 删除端口映射
//        String clientId = lazyServerPermeateClientMappingRemoveCommand.getClientId();
//        Integer visitorPort = lazyServerPermeateClientMappingRemoveCommand.getVisitorPort();
//        this.changeCloseSocket(clientId, visitorPort);
//        return remove;
//    }
//
//    /**
//     * 创建客户端的访问者
//     *
//     * @param clientId 客户端ID
//     */
    @Override
    public Result<Void> createVisitor(String clientId) {
        // 查询代理信息
//        LazyNettyServerPermeateClientMapping lazyNettyServerPermeateClientMapping = new LazyNettyServerPermeateClientMapping();
//        lazyNettyServerPermeateClientMapping.setIsDeleted(false);
//        lazyNettyServerPermeateClientMapping.setClientId(clientId);
        LambdaQueryWrapper<LazyNettyServerPermeateClientMappingDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(LazyNettyServerPermeateClientMappingDO::getId

                ,LazyNettyServerPermeateClientMappingDO::getClientId
                ,LazyNettyServerPermeateClientMappingDO::getClientTargetIp
                ,LazyNettyServerPermeateClientMappingDO::getClientTargetPort
                ,LazyNettyServerPermeateClientMappingDO::getFromProtocolType
                ,LazyNettyServerPermeateClientMappingDO::getIsSsl
                ,LazyNettyServerPermeateClientMappingDO::getServerId
                ,LazyNettyServerPermeateClientMappingDO::getVisitorPort
                ,LazyNettyServerPermeateClientMappingDO::getToProtocolType
                ,LazyNettyServerPermeateClientMappingDO::getVisitorPort
        );
        wrapper.eq(LazyNettyServerPermeateClientMappingDO::getIsDeleted,false);
        wrapper.eq(LazyNettyServerPermeateClientMappingDO::getClientId,clientId);
        List<LazyNettyServerPermeateClientMappingDO> list = lazyNettyServerPermeateClientMappingDOService.list(wrapper);
//        Result<List<LazyNettyServerPermeateClientMapping>> list = lazyNettyServerPermeateClientMappingRepository
//                .findList(lazyNettyServerPermeateClientMapping);
//        return
//                list.applyOther(internalNetworkPenetrationMappings -> {
//                    for (LazyNettyServerPermeateClientMapping networkPenetrationMapping : internalNetworkPenetrationMappings) {
//                        Integer visitorPort = networkPenetrationMapping.getVisitorPort();
//                        String clientTargetIp = networkPenetrationMapping.getClientTargetIp();
//                        Integer clientTargetPort = networkPenetrationMapping.getClientTargetPort();
//                        this.createVisitor(clientId, clientTargetIp, clientTargetPort, visitorPort);
//                    }
//                    return ResultFactory.successOf();
//                });
              for (LazyNettyServerPermeateClientMappingDO networkPenetrationMapping : list) {
                        Integer visitorPort = networkPenetrationMapping.getVisitorPort();
                        String clientTargetIp = networkPenetrationMapping.getClientTargetIp();
                        Integer clientTargetPort = networkPenetrationMapping.getClientTargetPort();
                        this.createVisitor(clientId, clientTargetIp, clientTargetPort, visitorPort);
                    }
        return null;
    }
//
//    /**
//     * 创建访客
//     *
//     * @param clientId         客户端ID
//     * @param clientTargetIp   客户端目标IP
//     * @param clientTargetPort 客户端目标端口
//     * @param visitorPort      访客端口
//     */
    private void createVisitor(String clientId, String clientTargetIp, Integer clientTargetPort, Integer visitorPort) {


        try {
            // 更新 客户端映射
            NettyTcpServerPermeateClientVisitorSocket nettyTcpServerPermeateClientVisitorSocket = NettyTcpServerPermeateClientVisitorSocket.NettyVisitorSocketBuilder
                    .builder()
                    .builderClientId(clientId)
                    .builderClientTargetIp(clientTargetIp)
                    .builderClientTargetPort(clientTargetPort)
                    .builderVisitorPort(visitorPort)
                    .builderChannelFlowAdapter(channelFlowAdapter)
                    .build();
            nettyTcpServerPermeateClientVisitorSocket.start();
        } catch (Exception e) {
            e.printStackTrace();
            log.error("客户端:{},网络端口:{},开放失败", clientId, visitorPort);
            throw new RuntimeException(e);
        }
    }
}